import math

import networkx as nx
import numpy as np
from matplotlib import pyplot as plt
from python.lib import json

from DHTOA1 import load_traffic_data, process_traffic_scenario, calculate_total_delay, semi_calculate_static_latency
from allocate_switches_with_es_optimized import allocate_switches_with_es_optimized, allocate_electric_with_es_optimized
from calculate_optical_delay import calculate_communication_delay
from electric_path_algo import allocate_paths, widest_path
from find_min_max_delay_path import optimize_reconfiguration, find_min_max_delay_path
from find_min_max_delay_path_optimize import classify_traffic_paths, compute_max_delay, dynamic_traffic_reconfiguration, \
    update_link_capacities
from find_min_max_delay_path_test import matrix_to_communication_pairs
from optimize import find_optimal_electric_paths, calculate_no_recon_utilization, find_recon_electric_optical_paths, \
    initialize_utilization, calculate_communication_metrics, calculate_network_metrics, calculate_communication_times
# from optimize import find_electric_path_pairs
from topo2 import build_hybrid_topology_shared_tor,visualize_topology
from switchesalgo import allocate_switches_with_es


topo1=build_hybrid_topology_shared_tor(num_tor=4)
topo2=build_hybrid_topology_shared_tor(num_tor=16)
topo3=build_hybrid_topology_shared_tor(num_tor=32)

# 加载流量数据
with open("traffic_matrices.json", 'r') as f:
    traffic_matrices = json.load(f)
 # 提取不同节点数量下的 all_to_all 流量矩阵
all_to_all_4 = traffic_matrices['4_nodes']['all_to_all']
# 计算流量矩阵中所有元素的和
all_to_all_4_sum = sum(sum(row) for row in all_to_all_4)
print("all_to_all_4_sum:", all_to_all_4_sum)
all_to_all_4_matrix = np.array(all_to_all_4)
all_to_all_4_dict = matrix_to_communication_pairs(all_to_all_4_matrix, node_prefix="ToR")
T0_pair=matrix_to_communication_pairs(all_to_all_4_matrix, node_prefix="ToR")
T0=[]
for pair in T0_pair:
    T0.append(pair)

burst_traffic_4= traffic_matrices['4_nodes']['burst_traffic']

all_to_all_burst_4= traffic_matrices['4_nodes']['all_to_all_burst']
all_to_all_burst_4_sum = sum(sum(row) for row in all_to_all_burst_4)
print("all_to_all_burst_4_sum:", all_to_all_burst_4_sum)
all_to_all_burst_4_matrix = np.array(all_to_all_burst_4)
all_to_all_burst_4_dict = matrix_to_communication_pairs(all_to_all_burst_4_matrix, node_prefix="ToR")
T_pair=matrix_to_communication_pairs(all_to_all_burst_4_matrix, node_prefix="ToR")
T=[]
for pair in T_pair:
    T.append(pair)
tor_switches = {'ToR1', 'ToR2', 'ToR3', 'ToR4'}
optical_switches = {'os1', 'os2'}


# 没有突发流量前的通信对的最优路径
paths0, util0, delays0 = allocate_switches_with_es_optimized(topo1, T, all_to_all_4_dict, tor_switches, optical_switches,
                                                k_paths=3)
# 有突发流量前的通信对的最优路径
paths, util, delays = allocate_switches_with_es_optimized(topo1, T, all_to_all_burst_4_dict, tor_switches, optical_switches,
                                                k_paths=3)
print("============测试===================")
print(paths)
print(type(paths))
print(util)
print(delays)
print("============测试===================")
print("\n=== 基础流量矩阵的最优路径和流量分配 ===")
for pair, path in paths0.items():
    print(f"通信对 {pair}: 路径 {'→'.join(path)}")

for pair, rate in util0.items():
    print(f"链路 {pair}: 当前利用率={rate:.2f} Gbps")

for pair, delay in delays0.items():
    status = f"{delay:.2f}s" if delay not in [None, float('inf')] else "超时/未分配"
    print(f"通信对 {pair}: {status}")

print("\n=== 基础流量矩阵+突发流量矩阵的最优路径和流量分配 ===")
for pair, path in paths.items():
    print(f"通信对 {pair}: 路径 {'→'.join(path)}")

for pair, rate in util.items():
    print(f"链路 {pair}: 当前利用率={rate:.2f} Gbps")

for pair, delay in delays.items():
    status = f"{delay:.2f}s" if delay not in [None, float('inf')] else "超时/未分配"
    print(f"通信对 {pair}: {status}")

print("****************************全更新算法**************************")
# 获取需要重构和不需要重构的通信对
recon_pairs, no_recon_pairs = classify_traffic_paths(all_to_all_burst_4_dict, paths0, paths)
for recon_pair in recon_pairs:
    print(f"需要重构的通信对: {recon_pair}")

for no_recon_pair in no_recon_pairs:
    print(f"不需要重构的通信对: {no_recon_pair}")
# 计算不需要重构通信对的时间延迟
for pair in no_recon_pairs:
    if pair in delays:
        print(f"不需要重构的通信对 {pair} 的延迟为 {delays[pair]}")


# 计算不需要重构通信对链路利用率
existing_utilization = calculate_no_recon_utilization(G=topo1, no_recon_pairs=no_recon_pairs,current_paths=paths,
                                             traffic_demand=all_to_all_burst_4_dict, tor_switches=tor_switches,
                                             k_paths=3)
print("\n=== 不需要重构的链路利用率 ===")
for pair, rate in existing_utilization.items():
    print(f"链路 {pair}: 当前已分配的流量为={rate:.2f} Gbps")

# 为需要重构的通信对寻找最优的电链路
# 获取不需要重构的通信对的流量需求
electric_path_allocations, link_utilization, recon_electric_delay_info = allocate_electric_with_es_optimized(G=topo1, T=recon_pairs, D=all_to_all_burst_4_dict,
                                                init_util=existing_utilization,tor_switches=tor_switches,optical_switches=optical_switches, k_paths=18)
print("\n=== 为需要重构的通信对寻找最优的电链路 ===")
for pair, path in electric_path_allocations.items():
    print(f"通信对 {pair}: 路径 {'→'.join(path)}")
for pair, rate in link_utilization.items():
    print(f"链路 {pair}: 当前已分配的流量={rate:.2f} Gbps")
for pair, delay in recon_electric_delay_info.items():
    status=delay
    if delay is None:
        print(f"{pair}:未分配路径")
    # status = f"{delay:.2f}s" if delay not in [None, float('inf')] else "超时/未分配"
    else:
        print(f"通信对 {pair}: {status}")

recon_optical_delays=find_recon_electric_optical_paths(G=topo1, traffic_demand=all_to_all_burst_4_dict,current_paths=paths,recon_electric_delay_info=recon_electric_delay_info,recon_delay=0.01)
# 合并不需要重构和需要重构的通信对延迟
delays_1={}
for pair in delays:
    if delays[pair] is None:
        continue
    else:
        delays_1[pair]=delays[pair]
for pair in recon_optical_delays:
    if pair in delays:
        # delays_1[pair]=0.0
        delays_1[pair] = recon_optical_delays[pair] + 10.0
        print(f"通信对{pair}进行了重构")
        print(f"需要重构的通信对 {pair}延迟: {delays_1[pair]}")
    else:
        print(f"通信对{pair}不需要重构,通信时间为原来的")
total_delays_1=0.0
max_delays_1=0.0
for pair in delays_1:
    if delays_1[pair] > max_delays_1:
        max_delays_1 = delays_1[pair]
    total_delays_1 += delays_1[pair]
print("***********输出全更新算法的每个通信对的延迟以及所有通信对的延迟和=======================")
for pair in delays_1:
    print(f"通信对 {pair}: {delays_1[pair]}")
print(f"全更新路由算法的最大延迟为：{max_delays_1}")
print(f"全更新路由算法所有通信对的延迟和为 {total_delays_1:.2f}s")
# print("===================测试====================")


print("==========================半更新路由算法（只更新电链路，不更新光链路）===========================")
# 获取通信对中最优路径为电链路的通信对及路径
need_recon_electric_pairs ={}
no_need_recon_pairs0 ={}
for pair in paths0:
    print(f"通信对 {pair}: 路径 {paths0[pair]}")
    # 遍历路径中的每一条链路
    for u, v in zip(paths0[pair], paths0[pair][1:]):
        # 如果链路类型为电链路，则更新路径
        if topo1[u][v].get('type', 'electrical') == 'electrical':
            need_recon_electric_pairs[pair] = paths0[pair]
            break
        no_need_recon_pairs0[pair]=paths0[pair]

# print("================测试================")
# for pair in no_need_recon_pairs0:
#     print(f"通信对 {pair}: 路径 {no_need_recon_pairs0[pair]}")
T_no_need_recon_pairs0=[]
for pair in no_need_recon_pairs0:
    T_no_need_recon_pairs0.append(pair)
print("不需要重构的通信对：")
existing_utilization0 = calculate_no_recon_utilization(G=topo1, no_recon_pairs=T_no_need_recon_pairs0,current_paths=paths0,
                                             traffic_demand=all_to_all_burst_4_dict, tor_switches=tor_switches,
                                             k_paths=3)
print("================测试================")

for pair, rate in existing_utilization0.items():
    print(f"链路 {pair}: 当前已分配的流量为={rate:.2f} Gbps")
print("================测试================")
# 遍历需要重构的通信对，将他们的电链路初始化已分配的流量为0.0
T=[]
for pair, path in need_recon_electric_pairs.items():
# for pair, path in paths0.items():
    print(f"通信对 {pair}: 路径 {'→'.join(path)}")
    T.append(pair)
    # 遍历路径中的每一条链路
    for u, v in zip(path, path[1:]):
        # 如果链路类型为电链路，则更新路径上已分配的流量为0.0
        if topo1[u][v].get('type') == 'electrical':
            print(f"链路 {(u, v)} 的已分配流量已重置为0.0")
            existing_utilization0[(u, v)]=0.0
            existing_utilization0[(v, u)]=0.0
        else:
            print(f"链路 {(u, v)} 的已分配流量未改变")


# T=[]
# for pair in  no_recon_pairs:
#     T.append(pair)
# # 基于不需要重构的通信对初始化每条链路上已经分配的流量
# communication_times0, link_allocations0=calculate_communication_metrics(topo1, all_to_all_burst_4_dict, T, paths0)
# # 如果链路在不在link_allocations0中，则初始化该链路的已分配流量为0.0,如果在则初始化为link_allocations0中对应的值
# for edge in topo1.edges():
#     if edge not in link_allocations0:
#         existing_utilization[edge]=0.0
#         existing_utilization[(edge[1],edge[0])]=0.0
#     else:
#         existing_utilization[edge]=link_allocations0[edge]
#         existing_utilization[(edge[1],edge[0])]=link_allocations0[edge]
# 为需要重构的通信对寻找最优的电链路
electric_path_allocations, link_utilization, recon_electric_delay_info = allocate_electric_with_es_optimized(G=topo1, T=T, D=all_to_all_burst_4_dict,
                                                init_util=existing_utilization0,tor_switches=tor_switches,optical_switches=optical_switches, k_paths=18)
for pair, path in electric_path_allocations.items():
    print(f"通信对 {pair}: 路径 {'→'.join(path)}")
for pair, rate in link_utilization.items():
    print(f"链路 {pair}: 当前已分配的流量={rate:.2f} Gbps")
for pair, delay in recon_electric_delay_info.items():
    status = f"{delay:.2f}s" if delay not in [None, float('inf')] else "超时/未分配"
    print(f"通信对 {pair}: {status}")

print("输出不需要重构的通信对的通信时间：")
T_2=[]
for pair in no_need_recon_pairs0:
    T_2.append(pair)
comm_time = calculate_communication_times(topo1, all_to_all_burst_4_dict, T_2, paths0)
for pair, time in comm_time.items():
    print(f"不需要重构的通信对 {pair}: 通信时间={time:.2f} s")

print("***********输出半更新算法的每个通信对的延迟以及所有通信对的延迟和=======================")
delays_2={}
for pair in comm_time:
    if comm_time[pair] is None:
        continue
    else:
        delays_2[pair]=comm_time[pair]
for pair in recon_electric_delay_info:
    # if pair in delays_2:
    delays_2[pair] = recon_electric_delay_info[pair]
    print(f"通信对{pair}进行了重构")
    print(f"需要重构的通信对 {pair}延迟: {delays_2[pair]}")
    # else:
    #     print(f"通信对{pair}不需要重构,通信时间为原来的")
total_delays_2=0.0
max_delays_2=0.0
for pair in delays_2:
    if delays_2[pair] > max_delays_2:
        max_delays_2 = delays_2[pair]
    print(f"通信对延迟为 {pair}: {delays_2[pair]}")
    total_delays_2 += delays_2[pair]
print(f"半更新路由算法的最大通信对延迟为 {max_delays_2:.2f}s")
print(f"半更新路由算法的所有通信对的延迟和为 {total_delays_2:.2f}s")


print("==================固定路由算法（纯走电链路）==================")
T_1=[]
for pair in paths:
    T_1.append(pair)
# 创建新的初始化字典，完全基于当前拓扑
util = initialize_utilization(topo1)
electric_path_allocations, link_utilization, recon_electric_delay_info = allocate_electric_with_es_optimized(G=topo1, T=T_1, D=all_to_all_burst_4_dict,
                                                init_util=util,tor_switches=tor_switches,optical_switches=optical_switches, k_paths=18)

for pair, path in electric_path_allocations.items():
    print(f"通信对 {pair}: 路径 {'→'.join(path)}")
for pair, rate in link_utilization.items():
    print(f"链路 {pair}: 当前已分配的流量={rate:.2f} Gbps")
for pair, delay in recon_electric_delay_info.items():
    status = f"{delay:.2f}s" if delay not in [None, float('inf')] else "超时/未分配"
    print(f"通信对 {pair}: {status}")

print("***********输出固定（只走电链路）算法的每个通信对的延迟以及所有通信对的延迟和=======================")
delays_3={}
total_delays_3=0.0
max_delays_3=0.0
for pair in recon_electric_delay_info:
    if recon_electric_delay_info[pair] is None:
        continue
    else:
        delays_3[pair]=recon_electric_delay_info[pair]
        print(f"通信对 {pair}延迟: {delays_3[pair]}")
for pair in delays_3:
    if delays_3[pair]>max_delays_3:
        max_delays_3=delays_3[pair]
    # print(f"通信对延迟为 {pair}: {delays_3[pair]}")
    total_delays_3 += delays_3[pair]
print(f"固定路由算法（纯电链路）的最大通信对延迟为 {max_delays_3:.2f}s")
print(f"固定路由算法（纯点链路）的所有通信对的延迟和为 {total_delays_3:.2f}s")

print("==================固定路由算法（光电混合链路）==================")
T_3=[]
for pair in paths0:
    print(f"通信对 {pair}: 路径 {'→'.join(paths0[pair])}")
    T_3.append(pair)
communication_times, link_allocations=calculate_communication_metrics(topo1, all_to_all_burst_4_dict, T_1, paths0)
for pair, time in communication_times.items():
    print(f"通信对 {pair}: 预估延迟={time:.2f}s")

print(type(link_allocations))
for pair, path in link_allocations.items():
    print(f"链路 {pair}已经分配的流量为:{link_allocations[pair]} ")

print("***********输出固定（光电混合链路）算法的每个通信对的延迟以及所有通信对的延迟和=======================")
delays_4={}
total_delays_4=0.0
max_delays_4=0.0
for pair in communication_times:
    if communication_times[pair] is None:
        continue
    else:
        delays_4[pair]=communication_times[pair]
        print(f"通信对 {pair}延迟: {delays_4[pair]}")
for pair in delays_4:
    if delays_4[pair] > max_delays_4:
        max_delays_4=delays_4[pair]
    # print(f"通信对延迟为 {pair}: {delays_4[pair]}")
    total_delays_4 += delays_4[pair]
print(f"固定路由算法（光电混合链路）的最大通信对延迟为 {max_delays_4:.2f}s")
print(f"固定路由算法（光电混合链路）的所有通信对的延迟和为 {total_delays_4:.2f}s")




